#ifndef   	UTILS_DEBUG_H_
# define   	UTILS_DEBUG_H_

# include <QString>
# include <QTextStream>
# include <QDebug>
#include <fstream>
#include <vector>
class QStringList;


namespace CGF
{
extern  int debug_level ;

class Logger: public std::ofstream
{
public:
	Logger(): std::ofstream()
	{
		open("log.txt");
	}


};

template<typename  T>
	Logger& operator<<( Logger& d, const std::vector<T>& rhs)
	{
	    for(int i = 0 ; i< rhs.size();i++)
			d <<rhs[i] <<" "; 
		return d;
	 }

class Debuger
{
  public:
    virtual ~Debuger()
    { qDebug() << "[DBG]" << s; }

  public:
    QString* stringPtr() const { return &s; }

  private:
    mutable QString s;
};

#define CGF_DECLARE_DEBUG_OPERATOR(Type) \
inline const Debuger& operator<<(const Debuger& d, Type rhs) \
{ QTextStream stream(d.stringPtr()); stream << rhs; return d; }

CGF_DECLARE_DEBUG_OPERATOR(bool)
CGF_DECLARE_DEBUG_OPERATOR(short)
CGF_DECLARE_DEBUG_OPERATOR(unsigned short)
CGF_DECLARE_DEBUG_OPERATOR(int)
CGF_DECLARE_DEBUG_OPERATOR(unsigned)
CGF_DECLARE_DEBUG_OPERATOR(long)
CGF_DECLARE_DEBUG_OPERATOR(unsigned long)
CGF_DECLARE_DEBUG_OPERATOR(long long)
CGF_DECLARE_DEBUG_OPERATOR(unsigned long long)
CGF_DECLARE_DEBUG_OPERATOR(double)
CGF_DECLARE_DEBUG_OPERATOR(const QString&)
CGF_DECLARE_DEBUG_OPERATOR(const char*)

const Debuger& operator<<(const Debuger& d, const std::string& rhs);

const Debuger& operator<<(const Debuger& d, const QStringList& rhs);

#ifndef NDEBUG
# define dbg(level) if (level <= CGF::debug_level) Debuger()
#else
# define dbg(level) if(0) Debuger()
#endif // ndef NDEBUG

# define log() Debuger()
# define log_error() Debuger() << "Error: "

#ifndef NDEBUG
# define dbg_print(value, level) \
		dbg(level) << #value": " << value;
#else
# define dbg_print(value, level)
#endif // ndef NDEBUG
}

#endif 
